package com.healthyeating.manage.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.healthyeating.common.utils.DateUtils;
import com.healthyeating.common.utils.SecurityUtils;
import com.healthyeating.manage.domain.Chat;
import com.healthyeating.manage.domain.dto.ChatRequest;
import com.healthyeating.manage.mapper.ChatMapper;
import com.healthyeating.manage.service.IDeepSeekService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

@Service
public class DeepSeekServiceImpl implements IDeepSeekService {

    @Resource
    private WebClient webClient;

    @Autowired
    private ChatMapper chatMapper;

    @Value("${deepseek.api.url}")
    private String url;

    @Value("${deepseek.api.api-key}")
    private String key;

    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 流式的自定义传输数据
     *
     * @param request
     * @return
     */
    @Override
    public Flux<String> chatByStream(HttpServletRequest request) {
        try {
            String requestBody = StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8);
            ChatRequest chatRequest = objectMapper.readValue(requestBody, ChatRequest.class);

            return webClient.method(HttpMethod.POST)
                    .uri(url)
                    .header("Authorization", "Bearer " + key)
                    .header("Content-Type", "application/json")
                    .contentType(MediaType.APPLICATION_JSON)
                    .accept(MediaType.TEXT_EVENT_STREAM)
                    .bodyValue(chatRequest)
                    .retrieve()
                    .bodyToFlux(String.class);
        } catch (IOException e) {
            throw new RuntimeException("转换请求体失败", e);
        }
    }

    /**
     * 查询对话记录列表
     *
     * @param chat 对话记录
     * @return 对话记录集合
     */
    @Override
    public List<Chat> selectChatList(Chat chat) {
        chat.setUserId(SecurityUtils.getUserId());
        return chatMapper.selectChatList(chat);
    }

    /**
     * 查询单个对话记录
     *
     * @param chatId 对话记录
     * @return 对话记录
     */
    @Override
    public Chat selectChatByChatId(Long chatId) {
        return chatMapper.selectChatByChatId(chatId);
    }

    /**
     * 新增对话记录
     *
     * @param chat 对话记录
     * @return 结果
     */
    @Override
    public int addChat(Chat chat) {
        chat.setUserId(SecurityUtils.getUserId());
        chat.setCreateTime(DateUtils.getNowDate());
        if (chat.getTitle() == null) {
            JSONArray body = (JSONArray) JSON.parse(chat.getMessageBody());
            JSONObject message = (JSONObject) body.get(0);
            String content = message.getString("content");
            // 安全截取，最多取5个字符
            chat.setTitle(content.substring(0, Math.min(content.length(), 5)));
        }
        return chatMapper.insertChat(chat);
    }

    /**
     * 修改对话记录
     *
     * @param chat 对话记录
     * @return 结果
     */
    @Override
    public int editChat(Chat chat) {
        return chatMapper.updateChat(chat);
    }

    /**
     * 删除对话记录
     *
     * @param chatId 对话记录主键
     * @return 结果
     */
    @Override
    public int removeChat(Long chatId) {
        return chatMapper.deleteChatByChatId(chatId);
    }

}

